package pl.un4giv3n.mightvsmagic.admin.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import pl.un4giv3n.mightvsmagic.action.PersistenceAction;
import pl.un4giv3n.mightvsmagic.entity.ActivityType;
import pl.un4giv3n.mightvsmagic.entity.User;
import pl.un4giv3n.mightvsmagic.entity.UserActivity;
import pl.un4giv3n.mightvsmagic.entity.UserType;
import pl.un4giv3n.mightvsmagic.utils.ActivityLogUtil;
import pl.un4giv3n.mightvsmagic.utils.wrappers.UserActivityWrapper;

/**
 * @author andrzejewskia go-to-admin-main page action
 */
public class ShowUserLogAction extends PersistenceAction {

	private static final long serialVersionUID = 1L;
	/**
	 * session user
	 */
	private User sessionAdmin;
	private long userId;
	private List<UserActivityWrapper> userActivities = new ArrayList<UserActivityWrapper>();
	private String username;
	private boolean hideFights;
	private boolean hideTrainings;
	private boolean hideWorks;
	
	@SuppressWarnings("unchecked")
	@Override
	public String execute() {
		EntityManager em = getEntityManager();
		sessionAdmin = getSessionUser(em);
		if (sessionAdmin == null
				|| sessionAdmin.getUserType() != UserType.ADMIN) {
			addActionError("Zaloguj się");
			em.close();
			return LOGIN;
		}
		User user = em.find(User.class, userId);
		if (user == null) {
			addActionError("Niepoprawny id usera");
			em.close();
			return ERROR;
		}
		username = user.getLogin();
		Query query = em.createNamedQuery("find.activities.older.than");
		query.setParameter("userId", userId);
		query.setParameter("time", System.currentTimeMillis() - ONE_WEEK);
		List<UserActivity> activities = query.getResultList();
		if(hideFights || hideTrainings || hideWorks){
			for (Iterator<UserActivity> iterator = activities.iterator(); iterator.hasNext();) {
				UserActivity activity = iterator.next();
				ActivityType activityType = activity.getActivityType();
				if(hideFights && (activityType == ActivityType.ATTACK_OTHER_USER || activityType == ActivityType.WAS_ATTACKED_BY_USER)){
					iterator.remove();
				}
				else if(hideTrainings && (activityType == ActivityType.TRAIN_START || activityType == ActivityType.TRAIN_END)){
					iterator.remove();
				}else if(hideWorks && (activityType == ActivityType.WORK_START ||  activityType == ActivityType.WORK_END)){
					iterator.remove();
				}
			}
		}
		Collections.sort(activities, new Comparator<UserActivity>() {

			@Override
			public int compare(UserActivity o1, UserActivity o2) {
				long o1time = o1.getTimeDone();
				long o2time = o2.getTimeDone();
				return (o1time < o2time ? -1 : (o1time == o2time ? 0 : 1));
			}

		});
		for (int i = activities.size()-1; i > 1; i--) {
			userActivities.add(toWrapper(activities.get(i), activities.get(i-1)));
		}
		em.getTransaction().begin();
		UserActivity activity = ActivityLogUtil
				.createActivity(
						user.getUserType() == UserType.ADMIN ? ActivityType.ADMIN_VIEWADMINLOG
								: ActivityType.ADMIN_VIEWPLAYERLOG, sessionAdmin
								.getId(), " Podgląd użytkownika: " + user.toString());
		em.persist(activity);
		em.flush();
		em.getTransaction().commit();
		em.close();
		return SUCCESS;
	}

	private UserActivityWrapper toWrapper(UserActivity currentActivity,
			UserActivity prevActivity) {
		String timeDiff = "";
		if(prevActivity != null){
			/*
			 * this is a bit tricky... Get time diff between activities in h:m:ss format.
			 * First we get difference in millis, then use / for longs, that will automatically give us
			 * number of seconds rounded down, use same to get minutes and hours. Then multiply minutes by 60 and substract
			 * it from total number of seconds, to get seconds left (less than minute) and same thing for hours
			 */
			long diff = currentActivity.getTimeDone()-prevActivity.getTimeDone();
			long secs = diff/1000; 
			long mins = secs/60;
			long hours = mins/60;
			if(mins > 0){
				secs -= (mins*60);
			}
			if(hours > 0){
				mins -= (hours*60);
			}
			timeDiff = hours+":"+mins+":"+secs;
		}
		UserActivityWrapper wrapper = new UserActivityWrapper(currentActivity, timeDiff);
		return wrapper;
	}

	public long getUserId() {
		return userId;
	}

	public void setUserId(long userId) {
		this.userId = userId;
	}

	public List<UserActivityWrapper> getUserActivities() {
		return userActivities;
	}

	public String getUsername() {
		return username;
	}

	public boolean isHideFights() {
		return hideFights;
	}

	public void setHideFights(boolean hideFights) {
		this.hideFights = hideFights;
	}

	public boolean isHideTrainings() {
		return hideTrainings;
	}

	public void setHideTrainings(boolean hideTrainings) {
		this.hideTrainings = hideTrainings;
	}

	public boolean isHideWorks() {
		return hideWorks;
	}

	public void setHideWorks(boolean hideWorks) {
		this.hideWorks = hideWorks;
	}

}
